﻿using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq.Expressions;
using System.Web.Mvc;

namespace Webbness.Mvc.Extensions
{
    public static class DatePickerExtension
    {
        public static string DatePicker(this HtmlHelper htmlHelper, string name, string value)
        {
            return "<script type=\"text/javascript\">" +
                   "$(function() {" +
                   "$(\"#" + name + "\").datepicker();" +
                   "});" +
                   "</script>" +
                   "<input type=\"text\" size=\"10\" value=\"" + value + "\" id=\"" + name + "\" name=\"" + name + "\"/>";
        }

        public static string DatePickerFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression)
        {
            return htmlHelper.DatePickerFor(expression, null);
        }

        public static string DatePickerFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, IDictionary<string, object> htmlAttributes)
        {
            return htmlHelper.DatePickerHelper(ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData).Model, ExpressionHelper.GetExpressionText(expression), htmlAttributes);
        }

        private static string DatePickerHelper(this HtmlHelper htmlHelper, object model, string expression, IDictionary<string, object> htmlAttributes)
        {
            return InputHelper(htmlHelper, InputType.Text, expression, model, false, true, true, htmlAttributes);
        }

        private static string InputHelper(HtmlHelper htmlHelper, InputType inputType, string name, object value, bool useViewData, bool setId, bool isExplicitValue, IDictionary<string, object> htmlAttributes)
        {
            ModelState state;
            name = htmlHelper.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(name);
            if (string.IsNullOrEmpty(name))
            {
                throw new ArgumentException("", "name");
            }
            var builder = new TagBuilder("input");
            builder.MergeAttributes(htmlAttributes);
            builder.MergeAttribute("type", HtmlHelper.GetInputTypeString(inputType));
            builder.MergeAttribute("name", name, true);

            string str = null; 
            DateTime thisDate;

            if (value == null)
            {
                str = null; 
            }
            else if(DateTime.TryParse(value.ToString(), out thisDate))
            {
                str = thisDate.ToShortDateString();
            }
            else
            {
                str = value.ToString();
            }

            var str3 = (string) GetModelStateValue(htmlHelper, name, typeof (string));
            builder.MergeAttribute("value", str3 ?? (useViewData ? EvalDate(htmlHelper, name) : str), isExplicitValue);
            if (setId)
            {
                builder.GenerateId(name);
            }
            if (htmlHelper.ViewData.ModelState.TryGetValue(name, out state) && (state.Errors.Count > 0))
            {
                builder.AddCssClass(HtmlHelper.ValidationInputCssClassName);
            }

            string script = "<script type=\"text/javascript\">" +
                            "$(function() {" +
                            "$(\"#" + name + "\").datepicker();" +
                            "});" +
                            "</script>";
            return script + builder;
        }

        private static object GetModelStateValue(HtmlHelper htmlHelper, string key, Type destinationType)
        {
            ModelState state;
            if (htmlHelper.ViewData.ModelState.TryGetValue(key, out state) && (state.Value != null))
            {
                return state.Value.ConvertTo(destinationType, null);
            }
            return null;
        }

        private static string EvalDate(HtmlHelper htmlHelper, string key)
        {
            return String.Format("{0:MM/dd/yyyy}", Convert.ToDateTime(htmlHelper.ViewData.Eval(key), CultureInfo.CurrentCulture));
        }
    }
}